package com.ruoyi.common.utils.kiam;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Arrays;

/**
 * 检验 票据合法性 工具类
 * sm3签名方法需要依赖 Bouncy Castle轻量级密码术包 1.60 *
 */
public class TokenUtil {

    static {
        try {
            Security.addProvider(new BouncyCastleProvider());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final char[] HEXES = {
            '0', '1', '2', '3',
            '4', '5', '6', '7',
            '8', '9', 'a', 'b',
            'c', 'd', 'e', 'f'
    };


    public static String getSignature(String pwd, String paramUrl, String signMethod) throws NoSuchProviderException, NoSuchAlgorithmException, UnsupportedEncodingException {


        if (StringUtils.isNotBlank(paramUrl)) {
            try {
                paramUrl = URLDecoder.decode(paramUrl, "UTF-8");
            } catch (Exception e) {
                throw new RuntimeException("生成signData失败:", e);
            }
        }

        String[] paraArray = new String[]{};
        if (StringUtils.isNotBlank(paramUrl)) {
            String[] queryArray = paramUrl.split("&");
            paraArray = ArrayUtils.addAll(queryArray, paraArray);
        }

        Arrays.sort(paraArray);

        StringBuffer buffer = new StringBuffer();
        buffer.append(pwd);
        buffer.append(":");

        for (int i = 0; i < paraArray.length; i++) {
            buffer.append(paraArray[i]);
            buffer.append("&");
        }
        buffer.deleteCharAt(buffer.length() - 1);
        buffer.append(":");
        buffer.append(pwd);
        String encode = null;
        System.out.println("signString:" + buffer.toString());
        if ("SM3".equals(signMethod)) {
            encode = SM3Util.hash(buffer.toString().getBytes(StandardCharsets.UTF_8));
        } else {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance(signMethod, "BC");
                md.update(buffer.toString().getBytes(StandardCharsets.UTF_8));
            } catch (NoSuchAlgorithmException e) {
                throw e;
            }
            encode = bytes2Hex(md.digest());
        }
        return encode;
    }

    public static String bytes2Hex(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(HEXES[(b >> 4) & 0x0F]);
            hex.append(HEXES[b & 0x0F]);
        }
        return hex.toString();
    }
}